#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "http_server.h"
#include "ota_handler.h"
#include "client_manager.h"

#define PORT 8080
#define BUFFER_SIZE 1024

void handle_request(int client_socket);
void send_file(int client_socket, const char *file_path);
void send_response(int client_socket, const char *status, const char *content_type, const char *body);

void start_http_server() {
    int server_socket, client_socket;
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_addr_len = sizeof(client_addr);

    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket < 0) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(PORT);

    if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Bind failed");
        close(server_socket);
        exit(EXIT_FAILURE);
    }

    if (listen(server_socket, 5) < 0) {
        perror("Listen failed");
        close(server_socket);
        exit(EXIT_FAILURE);
    }

    printf("Server running at http://localhost:%d\n", PORT);

    while (1) {
        client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_len);
        if (client_socket < 0) {
            perror("Accept failed");
            continue;
        }

        handle_request(client_socket);
        close(client_socket);
    }

    close(server_socket);
}
int start_ota(const char *ip) {
    // 这里写实际OTA逻辑，暂时返回0表示成功
    printf("Start OTA for IP: %s\n", ip);
    return 0;
}
#define BUF_SIZE 4096
void send_ota_file(int client_sock, const char *filename) {
    printf("[OTA] 开始发送文件: %s\n", filename);
    FILE *fp = fopen(filename, "rb");
    if (!fp) {
        printf("[OTA] 打开文件失败: %s\n", filename);
        return;
    }
    char header[256];
    snprintf(header, sizeof(header),
        "HTTP/1.1 200 OK\r\n"
        "Content-Type: application/octet-stream\r\n"
        "Content-Disposition: attachment; filename=\"%s\"\r\n"
        "Connection: close\r\n\r\n", filename);
    send(client_sock, header, strlen(header), 0);

    char buf[BUF_SIZE];
    int n, total = 0;
    while ((n = fread(buf, 1, BUF_SIZE, fp)) > 0) {
        send(client_sock, buf, n, 0);
        total += n;
        printf("[OTA] 已发送 %d 字节，总计 %d 字节\n", n, total);
    }
    fclose(fp);
    printf("[OTA] 文件发送完成，总计 %d 字节\n", total);
}
void handle_request(int client_socket) {
    char buffer[BUFFER_SIZE];
    read(client_socket, buffer, sizeof(buffer) - 1);
    buffer[sizeof(buffer) - 1] = '\0';

    printf("[DEBUG] 收到请求:\n%s\n", buffer); // 增加这一行
    struct sockaddr_in addr;
    socklen_t addr_len = sizeof(addr);
    getpeername(client_socket, (struct sockaddr*)&addr, &addr_len);
    printf("[DEBUG] 来自: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));

    if (strstr(buffer, "GET / ") != NULL || strstr(buffer, "GET /HTTP") != NULL || strstr(buffer, "GET / HTTP") != NULL) {
        send_file(client_socket, "public/index.html");
    } else if (strstr(buffer, "GET /api/uploadfile") != NULL) {
        send_file(client_socket, "uploads/ota.bin");
    } else if (strstr(buffer, "POST /ota-start") != NULL) {
        // 检查 body 是否为 "start_ota"
        printf("[OTA] enter\n");
        char *body = strstr(buffer, "\r\n\r\n");
        if (body && strstr(body, "start_ota")) {
            send_ota_file(client_socket, "uploads/ota.bin");
            send_response(client_socket, "200 OK", "text/plain", "OTA started");
        } else {
            send_response(client_socket, "400 Bad Request", "text/plain", "Invalid OTA request");
        }
    } else {
        send_response(client_socket, "404 Not Found", "text/plain", "Not Found");
    }
}

void send_file(int client_socket, const char *file_path) {
    struct stat file_stat;
    if (stat(file_path, &file_stat) < 0) {
        send_response(client_socket, "404 Not Found", "text/plain", "File not found");
        return;
    }

    int file_fd = open(file_path, O_RDONLY);
    if (file_fd < 0) {
        send_response(client_socket, "500 Internal Server Error", "text/plain", "Error reading file");
        return;
    }

    send_response(client_socket, "200 OK", "application/octet-stream", NULL);
    char file_buffer[BUFFER_SIZE];
    ssize_t bytes_read;

    while ((bytes_read = read(file_fd, file_buffer, sizeof(file_buffer))) > 0) {
        write(client_socket, file_buffer, bytes_read);
    }

    close(file_fd);
}

void send_response(int client_socket, const char *status, const char *content_type, const char *body) {
    char response[BUFFER_SIZE];
    if (body) {
        snprintf(response, sizeof(response),
                 "HTTP/1.1 %s\r\n"
                 "Content-Type: %s\r\n"
                 "Content-Length: %zu\r\n"
                 "Connection: close\r\n"
                 "\r\n"
                 "%s",
                 status, content_type, strlen(body), body);
    } else {
        snprintf(response, sizeof(response),
                 "HTTP/1.1 %s\r\n"
                 "Connection: close\r\n"
                 "\r\n",
                 status);
    }
    write(client_socket, response, strlen(response));
}